home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pctchnqs / 1990 / number5 / serial.cpp < prev    next >
C/C++ Source or Header  |  1990-10-06  |  9KB  |  241 lines

  1. /**************************************************************************
  2. *   SERIAL.CPP - Listing 2
  3. *   Written by Kevin D. Weeks, August 1990
  4. *   Compiles and runs under Borland Turbo C++ and Zortech C++.
  5. */
  6. #include <stdio.h>
  7. #include "serial.hpp"
  8. // initialize the tables for use by Int 14h. the enum's defined in
  9. // SERIAL.HPP (Buad_Rate, Parity, etc.) index into these tables
  10. unsigned int Serial_Comm::baud_table[8] = {0,0x20,0x40,0x60,
  11.                                         0x80,0xa0,0xc0,0xe0};
  12. unsigned int Serial_Comm::parity_table[3] = {8,0x18,0};
  13. unsigned int Serial_Comm::stop_table[2] = {0,4};
  14. unsigned int Serial_Comm::data_table[2] = {2,3};
  15. Serial_Comm  *Serial_Comm::open_flag = NULL;
  16. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  17. *   Null constructor. Sets the data attributes to arbitrary
  18. *   defaults. If some other values seem better, use them.           */
  19. Serial_Comm::Serial_Comm(void)
  20. {
  21.     com_port = Com_1;
  22.     baud_rate = Baud_1200;
  23.     parity = No_Parity;
  24.     stop_bits = Stop_Bits_1;
  25.     data_bits = Data_Bits_8;
  26.     buffer_size = DEFAULT_BUF_SIZE;
  27.     recv_buffer = new unsigned char[buffer_size];
  28.     send_buffer = new unsigned char[buffer_size];
  29. }
  30. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  31. *   Constructor - allows the user to specify start-up parameters.   */
  32. Serial_Comm::Serial_Comm(Com_Port port, Baud_Rate baud, Parity par,
  33.                          Stop_Bits stop, Data_Bits data)
  34. {
  35.     unsigned int    parameters;
  36.     com_port = port;
  37.     baud_rate = baud;
  38.     parity = par;
  39.     stop_bits = stop;
  40.     data_bits = data;
  41.     buffer_size = DEFAULT_BUF_SIZE;
  42.     recv_buffer = new unsigned char[buffer_size];
  43.     send_buffer = new unsigned char[buffer_size];
  44. }
  45. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  46. *   Destructor - closes the port if open and owned by this instance
  47. *   and frees the buffers.                                          */
  48. Serial_Comm::~Serial_Comm(void)
  49. {
  50.     close();
  51.     delete [buffer_size] recv_buffer;
  52.     delete [buffer_size] send_buffer;
  53.     recv_buffer = send_buffer = NULL;
  54. }
  55. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  56. *   First, set the local buffers for the assembly module. Then open
  57. *   the port and claim it. Fails if someone else owns the port.     */
  58. Result  Serial_Comm::open(void)
  59. {
  60.     unsigned int    parameters;
  61.     if (open_flag) return ERROR;
  62.     com_set_buffers(recv_buffer,send_buffer,buffer_size);
  63.     parameters = baud_table[baud_rate] | parity_table[parity] |
  64.                  stop_table[stop_bits] | data_table[data_bits];
  65.     if (com_open(com_port,parameters) != ERROR) {
  66.         open_flag = this;                   // claim the port
  67.         return OK;
  68.     }
  69.     return ERROR;
  70. }
  71. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  72. *   If the port is open and belongs to this instance, close it.     */
  73. void    Serial_Comm::close(void)
  74. {
  75.     if (open_flag == this) {
  76.         com_close();
  77.         open_flag = NULL;
  78.     }
  79. }
  80. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  81. *   Read whatever's in the local buffer into the client's buffer.
  82. *   Fail if someone else owns the port.                             */
  83. int  Serial_Comm::read(void *client_buffer)
  84. {
  85.     if (open_flag == this) return com_read(client_buffer);
  86.     else return -1;
  87. }
  88. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  89. *   Write the client's buffer. Fails if already sending or if
  90. *   someone else owns the port.                                     */
  91. Result   Serial_Comm::write(void *buffer, int num_bytes)
  92. {
  93.     if (open_flag == this) return (Result)com_write(num_bytes,buffer);
  94.     else return ERROR;
  95. }
  96. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  97. *   Read a single character from the receive buffer.                */
  98. int     Serial_Comm::read_char(void)
  99. {
  100.     if (open_flag == this) return com_read_char();
  101.     else return -1;
  102. }
  103. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  104. *   Write a single character out the port. Note: this method will
  105. *   fail if a message is currently being sent.                      */
  106. Result   Serial_Comm::write_char(unsigned char chr)
  107. {
  108.     if (open_flag == this) return com_write_char(chr);
  109.     else return ERROR;
  110. }
  111. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  112. *   Clear and re-initialize the recive buffer.                      */
  113. Result  Serial_Comm::clr_recv_buffer(void)
  114. {
  115.     if (open_flag == this || open_flag == NULL) {
  116.         com_clr_recv_buf();
  117.         return OK;
  118.     }
  119.     return ERROR;
  120. }
  121. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  122. *   Clear and re-initialize the send buffer. If currently sending
  123. *   the remainder of the message will be discarded and the trans-
  124. *   mit interrupt disabled.                                         */
  125. Result  Serial_Comm::clr_send_buffer(void)
  126. {
  127.     if (open_flag == this || open_flag == NULL) {
  128.         com_clr_send_buf();
  129.         return OK;
  130.     }
  131.     return ERROR;
  132. }
  133. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  134. *   Get the current port status.                                    */
  135. Comm_Status  Serial_Comm::get_status(void)
  136. {
  137.     Comm_Status stat;
  138.     if (open_flag == this || open_flag == NULL)
  139.         stat.value = com_get_status();
  140.     else stat.value = 0;
  141.     return stat;
  142. }
  143. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  144. *   Returns the number of bytes in the receive buffer.              */
  145. int  Serial_Comm::get_bytes_recvd(void)
  146. {
  147.     if (open_flag == this) return com_chars_recvd();
  148.     else return -1;
  149. }
  150. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  151. *   Returns the number of bytes sent from the current message.      */
  152. int  Serial_Comm::get_bytes_sent(void)
  153. {
  154.     if (open_flag == this) return com_chars_sent();
  155.     else return -1;
  156. }
  157. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  158. *   Specifies the com port to use.                                  */
  159. void    Serial_Comm::set_port(Com_Port port)
  160. {
  161.     com_port = port;
  162.     if (open_flag == this) {
  163.         close();
  164.         open();
  165.     }
  166. }
  167. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  168. *   Specifies the baud rate.                                        */
  169. void    Serial_Comm::set_baud_rate(Baud_Rate baud)
  170. {
  171.     baud_rate = baud;
  172.     if (open_flag == this) {
  173.         close();
  174.         open();
  175.     }
  176. }
  177. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  178. *   Specifies the parity.                                           */
  179. void    Serial_Comm::set_parity(Parity par)
  180. {
  181.     parity = par;
  182.     if (open_flag == this) {
  183.         close();
  184.         open();
  185.     }
  186. }
  187. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  188. *   Specifies the number of stop bits.                              */
  189. void    Serial_Comm::set_stop_bits(Stop_Bits stop)
  190. {
  191.     stop_bits = stop;
  192.     if (open_flag == this) {
  193.         close();
  194.         open();
  195.     }
  196. }
  197. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  198. *   Specifies the number of data bits.                              */
  199. void    Serial_Comm::set_data_bits(Data_Bits data)
  200. {
  201.     data_bits = data;
  202.     if (open_flag == this) {
  203.         close();
  204.         open();
  205.     }
  206. }
  207. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  208. *   Specifies the size of low-level buffers.                        */
  209. Result      Serial_Comm::set_buffer_size(int size)
  210. {
  211.     Bool    port_open = FALSE;
  212.     // close the port if it's open and owned by this instance
  213.     if (open_flag == this) {
  214.         port_open = TRUE;
  215.         close();
  216.     }
  217.     // free the original buffers, then change the buffer size and
  218.     // re-allocate the buffers.
  219.     delete [buffer_size] recv_buffer;
  220.     delete [buffer_size] send_buffer;
  221.     buffer_size = size;
  222.     recv_buffer = new unsigned char[buffer_size];
  223.     send_buffer = new unsigned char[buffer_size];
  224.     // if the port was open re-open it and re-set the buffers
  225.     if (port_open == TRUE) {
  226.         com_set_buffers(recv_buffer,send_buffer,buffer_size);
  227.         return open();
  228.     }
  229.     return OK;
  230. }
  231. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  232. unsigned int clock_ticks(int start)
  233. {
  234.     static long     reference;
  235.     static long far *bios_clock = (long far *)0x0040006c;
  236.  
  237.     if (start)
  238.         reference = *bios_clock;
  239.     return (unsigned int)((*bios_clock - reference) / 2);
  240. }
  241.